`include "DDRStruct.vh"

module Axi_lite_DDR #(
    parameter integer C_S_AXI_DATA_WIDTH = 64,
    parameter integer C_S_AXI_ADDR_WIDTH = 64,
    parameter longint MEM_DEPTH          = 64'd4096,
    parameter         FILE_PATH          = "testcase.hex"
) (
    AXI_ift.Slave  slave_ift,
    DDR_ift.Master ddr_request,

    output DDRStruct::DDRDebugCorePack ddr_debug_core
);

    Mem_ift #(
        .ADDR_WIDTH(C_S_AXI_ADDR_WIDTH),
        .DATA_WIDTH(C_S_AXI_DATA_WIDTH)
    ) mem_ift ();

    wire [1:0] debug_axi_wstate;
    wire [1:0] debug_axi_rstate;
    wire       debug_wen_mem;
    wire       debug_ren_mem;
    wire       debug_rvalid_mem;
    wire       debug_wvalid_mem;

    MemAxi_lite #(
        .C_S_AXI_DATA_WIDTH(C_S_AXI_DATA_WIDTH),
        .C_S_AXI_ADDR_WIDTH(C_S_AXI_ADDR_WIDTH)
    ) memaxi_lite (
        .slave_ift(slave_ift),
        .mem_ift  (mem_ift.Master),

        .debug_axi_wstate(debug_axi_wstate),
        .debug_axi_rstate(debug_axi_rstate),
        .debug_wen_mem   (debug_wen_mem),
        .debug_ren_mem   (debug_ren_mem),
        .debug_rvalid_mem(debug_rvalid_mem),
        .debug_wvalid_mem(debug_wvalid_mem)
    );

    reg old_en;
    always @(posedge slave_ift.clk) begin
        if (~slave_ift.rstn) begin
            old_en <= 1'b0;
        end else begin
            old_en <= mem_ift.Mw.wen | mem_ift.Mr.ren;
        end
    end

    reg [63:0] cnt;
    always @(posedge slave_ift.clk) begin
        if (~slave_ift.rstn) begin
            cnt <= 64'b0;
        end else if (old_en == 1'b0 & (mem_ift.Mw.wen | mem_ift.Mr.ren)) begin
            cnt <= cnt + 64'b1;
        end
    end
    wire [63:0] debug_visit_times = cnt;

    assign ddr_request.waddr_mem            = mem_ift.Mw.waddr;
    assign ddr_request.raddr_mem            = mem_ift.Mr.raddr;
    assign ddr_request.wdata_mem            = mem_ift.Mw.wdata;
    assign mem_ift.Sr.rdata                 = ddr_request.rdata_mem;
    assign mem_ift.Sr.rvalid                = ddr_request.rvalid_mem;
    assign mem_ift.Sw.wvalid                = ddr_request.wvalid_mem;
    assign ddr_request.wen_mem              = mem_ift.Mw.wen;
    assign ddr_request.ren_mem              = mem_ift.Mr.ren;
    assign ddr_request.wmask_mem            = mem_ift.Mw.wmask;

    assign ddr_debug_core.debug_axi_rstate  = debug_axi_rstate;
    assign ddr_debug_core.debug_axi_wstate  = debug_axi_wstate;
    assign ddr_debug_core.debug_wen_mem     = debug_wen_mem;
    assign ddr_debug_core.debug_ren_mem     = debug_ren_mem;
    assign ddr_debug_core.debug_rvalid_mem  = debug_rvalid_mem;
    assign ddr_debug_core.debug_wvalid_mem  = debug_wvalid_mem;
    assign ddr_debug_core.debug_visit_times = debug_visit_times;


endmodule
